


class FloorType
  BOTTOM='bottom'
  MIDDLE='middle'
  TOP='top'
end

def build_home
	$model.start_operation "build_home"
  $main_h_beam_length=(Grid.to_f*8).to_l

  creale_all_main_components

  dim_x = 2.m;
  dim_y = 2.m;
  levels  = 1;

  for l in 0..levels
    tr = Geom::Transformation.translation [0, 0, l*(Floor_height_g*Grid+Floor_joist_height)]
    if l==0
      name = make_level( dim_x, dim_y, FloorType::BOTTOM )
    elsif l==levels
      name = make_level( dimx_x, dim_y, FloorType::TOP )
    else
      name = make_level( dim_x, dim_y, FloorType::MIDDLE )
    end
    $entities.add_instance( $model.definitions[name], tr )
  end

  $model.commit_operation
  
  # print statistik
  floor_square = cells_x*Floor_module_x_g*Grid.to_m * cells_y*Floor_module_y_g*Grid.to_m * levels
  print_stats( floor_square )

end

def make_level ( cells_x, cells_y, floor_type )
  name = 'level_'+floor_type
  component = $model.definitions.add(name);
  floor_name = make_floor_from_cells( cells_x, cells_y, floor_type )
  tr = Geom::Transformation.new
  component.entities.add_instance( $model.definitions[floor_name], tr )
  
  # add walls using wall component
  if floor_type != FloorType::TOP
    wall_name = make_cell_wall
    for x in 0..cells_x-1
      tr = Geom::Transformation.translation [ x*Floor_module_x_g*Grid, 0, 0 ]
      component.entities.add_instance( $model.definitions[wall_name], tr )
    end
    wall_joist_name = make_joist("joist", Wall_joist_width, Wall_joist_height, Floor_height_g*Grid+Floor_joist_height)
    # end wall
    rot_x = Geom::Transformation.rotation ORIGIN, [1,0,0], Math::PI
    tr = Geom::Transformation.translation [ Floor_module_x_g*cells_x*Grid, 0, 0 ]
    component.entities.add_instance( $model.definitions[wall_joist_name], tr*rot_x )
    
    rot_z = Geom::Transformation.rotation ORIGIN, [0,0,1], Math::PI
    for x in 0..cells_x-1
      tr = Geom::Transformation.translation [ x*Floor_module_x_g*Grid+Floor_module_x_g*Grid, Floor_module_y_g*Grid*cells_y+Floor_joist_width, 0 ]
      component.entities.add_instance( $model.definitions[wall_name], tr*rot_z )
    end
    # end wall
    rot_x = Geom::Transformation.rotation ORIGIN, [1,0,0], Math::PI
    tr = Geom::Transformation.translation [ -Wall_joist_width, Floor_module_y_g*Grid*cells_y+Floor_joist_width+Wall_joist_height, 0 ]
    component.entities.add_instance( $model.definitions[wall_joist_name], tr*rot_x )
    
    rot_z = Geom::Transformation.rotation ORIGIN, [0,0,1], Math::PI/2
    for y in 0..cells_y-1
      tr = Geom::Transformation.translation [ Floor_module_x_g*Grid*cells_x+Floor_joist_width, y*Floor_module_y_g*Grid+0, 0 ]
      component.entities.add_instance( $model.definitions[wall_name], tr*rot_z )
    end
    # end wall
    rot_x = Geom::Transformation.rotation ORIGIN, [1,0,0], Math::PI
    tr = Geom::Transformation.translation [ Floor_module_x_g*cells_x*Grid+Wall_joist_height+Floor_joist_width, Floor_module_y_g*Grid*cells_y+Wall_joist_width, 0 ]
    component.entities.add_instance( $model.definitions[wall_joist_name], tr*rot_x*rot_z )
  end
  
  return name
end

def make_cell_wall
    name = 'cell_wall'
    component = $model.definitions.add(name);

    # add pillars
    joist_name = make_joist("joist", Wall_joist_width, Wall_joist_height, Floor_height_g*Grid+Floor_joist_height)
    rot_x = Geom::Transformation.rotation ORIGIN, [1,0,0], Math::PI
    for x in 0..Floor_module_x_g-1
      tr = Geom::Transformation.translation [ x*Grid, 0, 0 ]
      component.entities.add_instance( $model.definitions[joist_name], tr*rot_x )
    end
    
    # add middle and outer plates, first down-row
    rot_x = Geom::Transformation.rotation ORIGIN, [1,0,0], 0
    rot_z = Geom::Transformation.rotation ORIGIN, [0,0,1], Math::PI/2
    rot_y = Geom::Transformation.rotation ORIGIN, [0,1,0], -Math::PI/2
    tr_outer = Geom::Transformation.translation [ 0, -500.mm, 0]
    tr_main_insulation = Geom::Transformation.translation [ 0, -Insulation_main_thickness-Middle_wall_plate_strength, 0]
    for x in 0..Floor_module_x_g / Main_osb_plate_grid_y-1
      tr = Geom::Transformation.translation [ Main_osb_plate_grid_y*Grid + Wall_joist_width/2 +  x*Grid*Main_osb_plate_grid_y, -Wall_joist_height-Middle_wall_plate_strength, 0 ]
      # midle
      component.entities.add_instance( $model.definitions["middle_wall_plate"], tr*rot_z*rot_y )
      # outer
      component.entities.add_instance( $model.definitions["middle_wall_plate"], tr*tr_outer*rot_z*rot_y )
      component.entities.add_instance( $model.definitions["outer_plate"], tr*tr_main_insulation*rot_z*rot_y )     
    end
    # add middle rest-plates, second top-row
    top_plate_height = Floor_height_g*Grid+Floor_joist_height-Main_osb_plate_grid_x*Grid
    make_block_component ( "middle_wall_top_plate", top_plate_height, Main_osb_plate_grid_y*Grid, Middle_wall_plate_strength, $materials['OSB_1'] ) 
    make_block_component ( "outer_wall_top_plate", top_plate_height, Main_osb_plate_grid_y*Grid, Middle_wall_plate_strength, $materials['OSB_1'] ) 
    make_block_component ( "outer_top_plate", top_plate_height, Main_osb_plate_grid_y*Grid, Middle_wall_plate_strength, $materials['outer_plate'] ) 
    for x in 0..Floor_module_x_g / Main_osb_plate_grid_y-1
      tr = Geom::Transformation.translation [ Main_osb_plate_grid_y*Grid + Wall_joist_width/2 +  x*Grid*Main_osb_plate_grid_y, -Wall_joist_height-Middle_wall_plate_strength, Main_osb_plate_grid_x*Grid ]
      # middle
      component.entities.add_instance( $model.definitions["middle_wall_top_plate"], tr*rot_z*rot_y )
      # outer
      component.entities.add_instance( $model.definitions["outer_wall_top_plate"], tr*tr_outer*rot_z*rot_y )
      component.entities.add_instance( $model.definitions["outer_top_plate"], tr*tr_main_insulation*rot_z*rot_y )
      
    end
    
    # add inner plates, one row now
    #make_block_component ( "inner_wall_plate", Floor_height_g*Grid, Main_osb_plate_grid_y*Grid, Main_osb_plate_strength, $materials['OSB_1'] ) 
    for x in 0..Floor_module_x_g / Main_osb_plate_grid_y-1
      tr = Geom::Transformation.translation [ Main_osb_plate_grid_y*Grid + Wall_joist_width/2 +  x*Grid*Main_osb_plate_grid_y, 0, Floor_joist_height ]
      component.entities.add_instance( $model.definitions["gips_main_plate"], tr*rot_z*rot_y )
    end
    
    return name;
end

def make_floor_from_cells( cells_x, cells_y, floor_type )
  name = 'floor_from_cells_'+floor_type
  component = $model.definitions.add(name);
  floor_cell_name = make_floor_cell(floor_type)
  for x in 0..cells_x-1
    for y in 0..cells_y-1
      tr = Geom::Transformation.translation [ x*Floor_module_x_g*Grid, y*Floor_module_x_g*Grid, 0 ]
      component.entities.add_instance $model.definitions[floor_cell_name], tr
    end
  end
  
  # add joining joists on the other Y-end of cells cluster
  joist_name = make_joist("joist", Floor_joist_width, Floor_joist_height, Floor_module_x_g*Grid)
  rot_x = Geom::Transformation.rotation ORIGIN, [1,0,0], Math::PI/2
  rot_y = Geom::Transformation.rotation ORIGIN, [0,1,0], -Math::PI/2
  for x in 0..cells_x-1
    tr = Geom::Transformation.translation [ Floor_joist_width/2+x*Floor_module_x_g*Grid, Floor_joist_width+cells_y*Floor_module_x_g*Grid, 0 ]
    component.entities.add_instance $model.definitions[joist_name], tr * rot_x * rot_y
  end
  
  # add joining jois on the other X-end of cells cluster
  joist_name = make_joist("joist", Floor_joist_width, Floor_joist_height, Floor_module_x_g*Grid-Floor_joist_width)
  rot_x = Geom::Transformation.rotation ORIGIN, [1,0,0], Math::PI/2
  for y in 0..cells_y-1
    tr = Geom::Transformation.translation [ Floor_module_x_g*Grid*cells_x, y*Floor_module_x_g*Grid + Floor_joist_width, 0 ] 
    component.entities.add_instance $model.definitions[joist_name], tr * rot_x
  end
  
  return name
end

def make_floor_cell (floor_type)
  
  name = 'floor_cell_'+floor_type
  
  component = $model.definitions.add(name) ;  
  joist_name = make_joist("joist", Floor_joist_width, Floor_joist_height, Floor_module_x_g*Grid-Floor_joist_width)
  puts "createing floor cell with joist \""+joist_name+"\""
  # add main beams
  rot_x = Geom::Transformation.rotation ORIGIN, [1,0,0], Math::PI/2
  for x in 0..Floor_module_x_g - 1
    tr = Geom::Transformation.translation [ x*Grid, Floor_joist_width, 0 ] 
    component.entities.add_instance( $model.definitions[joist_name], tr*rot_x )
  end
  
  # add side beam
  joist_name = make_joist("joist", Floor_joist_width, Floor_joist_height, Floor_module_x_g*Grid)
  rot_x = Geom::Transformation.rotation ORIGIN, [1,0,0], Math::PI/2
  rot_y = Geom::Transformation.rotation ORIGIN, [0,1,0], -Math::PI/2
  tr = Geom::Transformation.translation [ Floor_joist_width/2, Floor_joist_width, 0 ] 
  component.entities.add_instance( $model.definitions[joist_name], tr*rot_x*rot_y )

  # add floor ad ceiling plates
  tr_bottom = Geom::Transformation.translation [ 0, 0, -Floor_joist_height-Main_osb_plate_strength]
  tr_gips_bottom = Geom::Transformation.translation [ 0, 0, -Floor_joist_height-Main_osb_plate_strength-Main_osb_plate_strength]
  tr_gips_top = Geom::Transformation.translation [ 0, 0, Main_osb_plate_strength]
  tr_floor_cover = Geom::Transformation.translation [ 0, 0, 1.5*Main_osb_plate_strength]
  tr_main_insulation = Geom::Transformation.translation [ 0, 0, Insulation_main_thickness]
  for x in 0..Floor_module_x_g / Main_osb_plate_grid_x-1
    for y in 0..Floor_module_x_g/Main_osb_plate_grid_y-1
      tr = Geom::Transformation.translation [ x*Grid*Main_osb_plate_grid_x+Floor_joist_width/2, y*Grid*Main_osb_plate_grid_y+Floor_joist_width/2, Floor_joist_height+Main_osb_plate_strength ] 
      component.entities.add_instance( $model.definitions['osb_main_plate'], tr )
      component.entities.add_instance( $model.definitions['osb_main_plate'], tr*tr_bottom )
      if floor_type == FloorType::TOP
        component.entities.add_instance( $model.definitions["outer_plate"], tr*tr_main_insulation )     
      else
        component.entities.add_instance( $model.definitions["gips_main_plate"], tr*tr_gips_top )
        component.entities.add_instance( $model.definitions["floor_cover"], tr*tr_floor_cover )
      end
      if floor_type == FloorType::BOTTOM
        component.entities.add_instance( $model.definitions["outer_plate"], tr*tr_bottom*tr_main_insulation.clone.invert! )     
      else
        component.entities.add_instance( $model.definitions["gips_main_plate"], tr*tr_gips_bottom )
      end
    end
  end
  return name
end

def make_floor ( size_x_g, size_y_g )
  
  # assert if provided dimentions are compatible with plate dimentions
  if size_x_g % Main_osb_plate_grid_x != 0
    raise Exception, "grid_x do not divide by "+Main_osb_plate_grid_x.to_s
  end
  if size_y_g % Main_osb_plate_grid_y != 0
    raise Exception, "grid_y do not divide by "+Main_osb_plate_grid_x.to_s
  end
  
  component = $model.definitions.add('floor') ;  
  # add floor plates
  cnt=0
  for x in 0..size_x_g / Main_osb_plate_grid_x-1
    for y in 0..size_y_g/Main_osb_plate_grid_y-1
      trans = Geom::Transformation.translation [ x*Grid*Main_osb_plate_grid_x, y*Grid*Main_osb_plate_grid_y, Main_osb_plate_strength ] 
      component.entities.add_instance( $model.definitions['osb_main_plate'], trans )
      cnt += 1
    end
  end
  puts "unsig "+cnt.to_s+" floor plates"

  # add supporting ribs
  make_block_component("rib", Floor_ribs_height_g*Grid, Main_osb_plate_strength, Floor_ribs_length_g*Grid, $materials['OSB_1'])
  rotation_y = Geom::Transformation.rotation ORIGIN, [0,1,0], -Math::PI/2
  rotation_x = Geom::Transformation.rotation ORIGIN, [1,0,0], Math::PI/2
  local_correction = Geom::Transformation.translation [+Main_osb_plate_strength,0,-Floor_ribs_height_g*Grid]
  
  cnt=0
  for x in 0..size_x_g/Main_osb_plate_grid_x-1
    puts "x "+x.to_s
    for y in 0..size_y_g/Floor_ribs_length_g-1
      puts "y "+y.to_s
      steps=Main_osb_plate_grid_x / Floor_ribs_distance_g
      for k in 0..steps
        puts "k "+k.to_s
        plate_thickness_corr=Main_osb_plate_strength / steps
        step = Geom::Transformation.translation [ x*Grid*Main_osb_plate_grid_x+k*(Grid*Floor_ribs_distance_g-plate_thickness_corr), y*Grid*Floor_ribs_length_g, 0 ] 
        componnent.entities.add_instance( $model.definitions["rib"], step * local_correction * rotation_y * rotation_x)
        cnt += 1
      end
    end
  end
  puts "unsig "+cnt.to_s+" ribs"
  
  
end

